package com.xiangxiao.rpan.authority.service.impl;

import com.xiangxiao.rpan.authority.constant.GlobalConsts;
import com.xiangxiao.rpan.authority.dao.*;
import com.xiangxiao.rpan.authority.dto.MenuQueryDto;
import com.xiangxiao.rpan.authority.dto.ModuleQueryDto;
import com.xiangxiao.rpan.authority.dto.ModuleTreeParam;
import com.xiangxiao.rpan.authority.model.*;
import com.xiangxiao.rpan.authority.service.IRoleService;
import com.xiangxiao.rpan.authority.tree.Tree;
import com.xiangxiao.rpan.authority.tree.TreeNode;
import com.xiangxiao.rpan.authority.utils.TreeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Projectname: RoleServiceImpl
 * @Author: xiangxiao
 * @Email: 573768011@qq.com
 * @Data:2023/3/26 1:55
 */
@Service
public class RoleServiceImpl implements IRoleService {
  @Autowired
  private RoleMapper roleMapper;
  @Autowired
  private ModuleMapper moduleMapper;
  @Autowired
  private MenuMapper menuMapper;
  @Autowired
  private OperationMapper operationMapper;
  @Autowired
  private RoleModulePermissionMapper roleModulePermissionMapper;
  @Override
  public List<UserRoleInfo> findRoleInfoOfUser(Long userId, Integer clientType) {
    return roleMapper.findRoleInfoOfUser(userId, clientType);
  }

  /**
   * 返回当前用户所有的操作
   *
   * @param userId 用户id
   * @return 返回用户的所有接口权限
   */
  @Override
  public List<Operation> findAllOperationListByUserId(Long userId) {
    List<Long> list = this.findModuleIdByUserId(userId);
    list.add(Long.valueOf(GlobalConsts.INIT_COMMON_MODULE_ID));
    List<Long> operationIds = operationMapper.findOperationIdsByModuleIds(list);
    if (CollectionUtils.isNotEmpty(operationIds)) {
      List<Operation> listOperation = operationMapper.findListOperationByIds(operationIds);
      if (CollectionUtils.isNotEmpty(listOperation)) {
        return listOperation;
      }
    }
    return new ArrayList<>();
  }

  @Override
  public List<Long> listRoleIdOfUser(Long userId) {
    return roleMapper.listRoleIdOfUser(userId, null);
  }

  @Override
  public List<Long> findModuleIdByUserId(Long userId) {
    List<Long> listRemoval = new ArrayList<>();
    List<Long> moduleIds = new ArrayList<>();
    // 根据用户id查询所有的角色id
    List<Long> roles = listRoleIdOfUser(userId);
    List<Long> newRoleIdList = new ArrayList<>();
    List<Role> roleList = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(roles)) {
      roleList = roleMapper.findRoleListBatch(roles);
    }
    if (CollectionUtils.isNotEmpty(roleList)) {
      for (Role role : roleList) {
        newRoleIdList.add(role.getId());
      }
    };

    List<Long> newModuleIds = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(newRoleIdList)) {
      for (Long role : newRoleIdList) {
        // 根据角色id查询所有的角色模块管理信息
        List<RoleModulePermission> roleModulePermissions =
          roleModulePermissionMapper.findRoleModulePermissionlistByRoleId(role);
        if (CollectionUtils.isNotEmpty(roleModulePermissions)) {
          for (RoleModulePermission roleModulePermission : roleModulePermissions) {
            // 更据模块id查询出所有的模块菜单信息
            moduleIds.add(roleModulePermission.getModuleId());
          }
        }
      }
      if (moduleIds.size() > 0) {
        // 根据当前id查询下级所有id
        newModuleIds.addAll(moduleIds);
        ModuleTreeParam moduleTreeParam = new ModuleTreeParam();
        List<ModuleQueryDto> allArea = moduleMapper.queryModuleListByModuleTreeParam(moduleTreeParam);
        // build成一个tree
        Tree tree = TreeUtil.buildTree(allArea, ModuleQueryDto.class);
        for (Long modueId : moduleIds) {
          List<Long> childrenIds = new ArrayList<>();
          List<TreeNode> treeNodes = new ArrayList<>();
          TreeUtil.filterAreaTreeNodes(treeNodes, modueId, tree, ModuleQueryDto.class);
          // 从树中取出所有的orgid
          childrenIds = TreeUtil.recursionByTreeNodes(treeNodes, childrenIds);
          if (childrenIds != null && childrenIds.size() > 0) {
            newModuleIds.addAll(childrenIds);
          }
        }
        // 根据当前id查询所有上级id
        for (Long modueId : moduleIds) {
          List<Long> childrenIds = new ArrayList<>();
          childrenIds = getTreeModuleParentIpList(childrenIds, modueId, tree, tree, "allTree");
          if (childrenIds.size() > 0) {
            newModuleIds.addAll(childrenIds);
          }
        }
        // 去重
        for (Long in : newModuleIds) {
          if (!listRemoval.contains(in)) {
            listRemoval.add(in);
          }
        }
        return listRemoval;
      }
    }
    return listRemoval;
  }

  /**
   * 模块递归父节点
   *
   * @param ids      结果
   * @param moduleId 从哪个moduleId节点开始向上递归
   * @param allTree  模块树数据源
   * @param downTree 模块树数据源，递归过程中逐渐变小
   * @param treeStr  用哪个tree "allTree"或者"downTree"，allTree代表整个树，downTree代表部门树
   * @return
   */
  @Override
  public List<Long> getTreeModuleParentIpList(List<Long> ids, Long moduleId, Tree allTree, Tree downTree,
                                              String treeStr) {
    if (allTree == null || downTree == null) {
      return new ArrayList<>();
    } else {
      Tree tree = null;
      if ("allTree".equals(treeStr)) {
        tree = allTree;
      } else {
        tree = downTree;
      }
      ModuleQueryDto area = tree.treeNode(ModuleQueryDto.class, moduleId);
      if (area != null) {
        ids.add(moduleId);
        Long parentId = area.getParentId();
        // 0代表顶级节点
        Long rootNode = 0L;
        if (rootNode.equals(parentId)) {
          return ids;
        } else {
          getTreeModuleParentIpList(ids, parentId, allTree, downTree, "allTree");
        }
      } else {
        Tree tree1 = null;
        for (int i = 0, ii = tree.getRootList().size(); i < ii; i++) {
          List<ModuleQueryDto> allArea = tree.child(ModuleQueryDto.class, tree.getRootList().get(i).getId());
          Tree.TreeBuilder builder = Tree.TreeBuilder.newInstance();
          if (CollectionUtils.isNotEmpty(allArea)) {
            builder.add(ModuleQueryDto.class, allArea);
            tree1 = builder.build();
          }
          if (tree1 != null) {
            getTreeModuleParentIpList(ids, moduleId, allTree, tree1, "downTree");
          }
        }
      }
    }
    return ids;
  }

  /**
   * 登录返回权限信息
   *
   * @param userId 用户id
   * @return 返回用户的菜单以及菜单接口权限集合
   */
  @Override
  public List<AuthModuleInfo> findAuthorityByUserIds(Long userId, List<Long> list) {
//   List<Long> list = findModuleIdByUserId(userId);
    if (CollectionUtils.isNotEmpty(list)) {
      return moduleMapper.findAuthorityInfos(list);
    }
    return new ArrayList<>();

  }

  /**
   * 返回权限数据树
   *
   * @param authorityInfoList 权限数据集合
   * @param moduleIds
   * @return 返回一颗菜单以及菜单接口的树
   */
  @Override
  public List<TreeNode> findAuthorityTree(List<AuthModuleInfo> authorityInfoList, List<Long> moduleIds, Set<Long> roleIds) {
    List<Long> list = new ArrayList<>();
    List<Long> resultList = new ArrayList<>();
    List<Long> authorityMenuIdList = new ArrayList<>();

    if (CollectionUtils.isNotEmpty(authorityInfoList)) {
      for (AuthModuleInfo authorityInfo : authorityInfoList) {
        authorityMenuIdList.add(authorityInfo.getId());
      }
      List<MenuQueryDto> menuQueryDtoList = menuMapper.findAllMenuTree();
      Tree tree = TreeUtil.buildTree(menuQueryDtoList, MenuQueryDto.class);
      for (AuthModuleInfo authorityInfo : authorityInfoList) {
        List<Long> ids = TreeUtil.getTreeParentIdList(list, authorityInfo.getId(), tree, tree, "allTree",
          MenuQueryDto.class);
        boolean doDistinct = CollectionUtils.isNotEmpty(ids) && CollectionUtils.isNotEmpty(authorityMenuIdList);
        if (doDistinct) {
          // 去重
          for (Long id : ids) {
            if (!authorityMenuIdList.contains(id)) {
              resultList.add(id);
            }
          }
        }
      }
    }
    if (CollectionUtils.isNotEmpty(resultList)) {
      List<Menu> menus = menuMapper.findListMenuByMenuIds(resultList);
      if (CollectionUtils.isNotEmpty(menus)) {
        AuthModuleInfo authorityInfo = null;
        for (Menu menu : menus) {
          authorityInfo = new AuthModuleInfo();
          authorityInfo.setId(menu.getId());
          authorityInfo.setParentId(menu.getPid());
          authorityInfo.setUrl(menu.getUrl());
          authorityInfo.setResourceCode(menu.getResourceCode());
          authorityInfoList.add(authorityInfo);
        }
      }
    }

    Tree tree = TreeUtil.buildTree(authorityInfoList, AuthModuleInfo.class);
    List<TreeNode> treeNodes = new ArrayList<>();

    TreeUtil.filterAreaTreeNodes(treeNodes, 0L, tree, AuthModuleInfo.class);
    return treeNodes;
  }
}
